<template>
  <div class="home" id="home" ref="home"></div>
  <div
    @click="add"
    style="
      position: absolute;
      top: 100px;
      left: 100px;
      z-index: inx;
      color: aquamarine;
    "
  >
    当前总分{{ totalScore }}
  </div>
  <div
    @click="jian"
    style="
      position: absolute;
      top: 200px;
      left: 100px;
      z-index: inx;
      color: aquamarine;
    "
  >
  当前队伍最高分{{ HighScore }}--{{ HighScoreAVE }}%
  </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import addGeoMetry from './addGeoMetry.js'
import { gsap } from "gsap";

import circle from './line.js'
import { CSS2DRenderer } from 'three/addons/renderers/CSS2DRenderer.js'
import tag from './tag.js'
import particle from './particle.js'
let camera = null
let renderer = null
let labelRenderer = null
export default {
  name: 'lesson8',
  data() {
    return {
      K: 5,
      labelLst: [],
      totalScore: 100, // 初始总分
      HighScore: 0, // 最高分
      HighScoreAVE: 0, // 最高分和总分的比值
      increaseInterval: null, // 用于保存 setInterval 的引用
    }
  },
  computed: {
    list: function () {
      var that = this
      var list = [
        {
          name: '太阳',
          R: 10 * that.K, //天体半径
          URL: 'img/taiyang.jpg', //天体纹理路径
          revolutionR: 0,
          score: 0, // 太阳没有得分字段
          orbit: null, // 每个行星都有一个轨道
        },
        {
          name: '水星',
          R: 2.5 * that.K, //天体半径
          URL: 'img/shuixing.jpg', //天体纹理路径
          revolutionR: 120 * this.K, //公转半径
          score: 0, // 太阳没有得分字段
          orbit: null, // 每个行星都有一个轨道
        },
        {
          name: '金星',
          R: 3 * that.K, //天体半径
          URL: 'img/jinxing.jpg', //天体纹理路径
          revolutionR: 120 * this.K, //公转半径
          score: 0, // 太阳没有得分字段
          orbit: null, // 每个行星都有一个轨道
        },
        {
          name: '地球',
          R: 3.2 * that.K, //天体半径
          URL: 'img/diqiu.jpg', //天体纹理路径
          revolutionR: 120 * this.K, //公转半径
          score: 0, // 太阳没有得分字段
          orbit: null, // 每个行星都有一个轨道
        },
        {
          name: '火星',
          R: 3.2 * that.K, //天体半径
          URL: 'img/huoxing.jpg', //天体纹理路径
          revolutionR: 120 * this.K, //公转半径
          score: 0, // 太阳没有得分字段
          orbit: null, // 每个行星都有一个轨道
        },
        {
          name: '木星',
          R: 5 * that.K, //天体半径
          URL: 'img/muxing.jpg', //天体纹理路径
          revolutionR: 120 * this.K, //公转半径
          score: 0, // 太阳没有得分字段
          orbit: null, // 每个行星都有一个轨道
        },
        {
          name: '土星',
          R: 3.5 * that.K, //天体半径
          URL: 'img/tuxing.jpg', //天体纹理路径
          revolutionR: 120 * this.K, //公转半径
          score: 0, // 太阳没有得分字段
          orbit: null, // 每个行星都有一个轨道
        },
        {
          name: '天王星',
          R: 3.5 * that.K, //天体半径
          URL: 'img/tianwangxing.jpg', //天体纹理路径
          revolutionR: 120 * this.K, //公转半径
          score: 0, // 太阳没有得分字段
          orbit: null, // 每个行星都有一个轨道
        },
        {
          name: '海王星',
          R: 4 * that.K, //天体半径
          URL: 'img/haiwangxing.jpg', //天体纹理路径
          revolutionR: 120 * this.K, //公转半径
          score: 0, // 太阳没有得分字段
          orbit: null, // 每个行星都有一个轨道
        },
      ]
      return list
    },
  },
  mounted() {
    this.initThree()
    window.addEventListener('resize', this.onWindowResize)
    // this.startScoreUpdate() // 开始更新分数
  },
  methods: {
    add() {
      // 当水星队伍得分时
      this.increaseScore('地球')
      this.increaseScore('金星')
     
    },
    jian(){ this.retreatPlanets()},
    initThree() {
      var that = this

      // 创建场景
      var scene = new THREE.Scene()
      // 新增：添加点光源，模拟太阳的光源效果
      // 添加多个点光源，分别放置在不同的位置
      const light1 = new THREE.PointLight(0xffffff, 3, 10000)
      light1.position.set(1000, 1000, 1000) // 放在场景上方的某个位置
      scene.add(light1)

      const light2 = new THREE.PointLight(0xffffff, 3, 10000)
      light2.position.set(-1000, -1000, -1000) // 放在场景的另一侧
      scene.add(light2)
      const light3 = new THREE.PointLight(0xffffff, 3, 10000)
      light2.position.set(-100, -100, -100) // 放在场景的另一侧
      scene.add(light3)
      // 添加环境光，照亮整个场景
      const ambientLight = new THREE.AmbientLight(0xffffff, 0.5) // 光的强度可以根据需求调整
      scene.add(ambientLight)
      // 创建网格模型

      var geometry = new THREE.SphereGeometry(1, 100, 100)

      // 创建轨道
      var arc = new THREE.ArcCurve(0, 0, 1, 0, 2 * Math.PI, true)

      // 标签创建
      labelRenderer = new CSS2DRenderer()
      labelRenderer.setSize(window.innerWidth, window.innerHeight)
      labelRenderer.domElement.style.position = 'absolute'
      // 相对标签原位置位置偏移大小
      labelRenderer.domElement.style.top = '0px'
      labelRenderer.domElement.style.left = '0px'
      // //设置.pointerEvents=none，以免模型标签HTML元素遮挡鼠标选择场景模型
      labelRenderer.domElement.style.pointerEvents = 'none'
      // 创建固定的轨道线，作为参考
      this.createFixedOrbits(scene)
      // 获取点数越多，圆弧越光滑
      var points = arc.getPoints(100) //返回一个vector2对象作为元素组成的数组
      var lineGeometry = new THREE.BufferGeometry()
      //setFromPoints方法的本质：遍历points把vector2转变化vector3
      lineGeometry.setFromPoints(points)
      var material = new THREE.LineBasicMaterial({
        color: 0x0f4984,
      })

      // 繁星

      var plan = particle()
      scene.add(plan)
      // 创建太阳的几何体和发光材质
      const sunGeometry = new THREE.SphereGeometry(10 * this.K, 100, 100)
      const sunMaterial = new THREE.MeshBasicMaterial({
        color: 0xffff00, // 太阳的颜色为黄色
      })
      const sunMesh = new THREE.Mesh(sunGeometry, sunMaterial)
      sunMesh.position.set(0, 0, 0) // 将太阳放置在场景中心
      scene.add(sunMesh)
      sunMesh.position.set(0, 0, 0) // 将太阳放置在场景中心

      this.list.forEach((type, index) => {
        //       const material = new THREE.MeshBasicMaterial({
        //   map: new THREE.TextureLoader().load(type.URL), // 行星的纹理
        // });
        // var mesh = addGeoMetry(geometry, type.URL, type.R)
        // mesh.name = type.name
        // mesh.data = type
        // mesh.angle = 2 * Math.PI * Math.random();
        const material = new THREE.MeshStandardMaterial({
          map: new THREE.TextureLoader().load(type.URL),
          roughness: 0.7, // 表面粗糙度
          metalness: 0.5, // 金属感
        })
        const mesh = new THREE.Mesh(geometry, material) // 使用 MeshBasicMaterial 代替其他材质
        mesh.scale.set(type.R, type.R, type.R) // 根据行星半径缩放
        mesh.name = type.name
        mesh.data = type
        mesh.angle = 2 * Math.PI * Math.random() // 设置初始随机角度
        scene.add(mesh) // 将行星添加到场景中
        mesh.material = material // 设置为新材质
        scene.add(mesh) //网格模型添加到场景中
        // 添加标签
        var group = scene.getObjectByName(type.name)
        var label = tag(group.name) //把名称obj.name作为标签
        var pos = new THREE.Vector3()
        group.getWorldPosition(pos) //获取obj世界坐标、
        label.position.copy(pos) //标签标注在obj世界坐标
        label.name = group.name
        scene.add(label) //标签插入model组对象中
        that.labelLst.push(label)
        // 添加标签
        // 创建轨道
        if (type.revolutionR) {
          var line = circle(lineGeometry, material, type.revolutionR)
          // scene.add(line)
        }
      })

      //环境光
      const ambient = new THREE.AmbientLight(0x404040, 0.6) // 调整光的强度
      scene.add(ambient)
      /**
       * 相机设置
       */
      const width = this.$refs.home.clientWidth
      const height = this.$refs.home.clientHeight
      //创建相机对象
      camera = new THREE.PerspectiveCamera(45, width / height, 1, 3000)
      camera.position.set(
        835.0912850575463,
        835.0912850575461,
        334.0365140230186
      ) //设置相机位置
      camera.lookAt(scene.position) //设置相机方向(指向的场景对象)

      /**
       * 创建渲染器对象
       */
      renderer = new THREE.WebGLRenderer({
        antialias: true, //开启锯齿
      })
      renderer.setSize(width, height) //设置渲染区域尺寸
      this.$refs.home.appendChild(renderer.domElement)
      that.$refs.home.appendChild(labelRenderer.domElement)

      // 渲染函数
      function render() {
        scene.children.forEach((type) => {
          if (
            type.type === 'Mesh' &&
            type.data &&
            type.data.revolutionR !== undefined &&
            type.data.revolutionR !== 0
          ) {
            // 太阳不参与逻辑
            type.rotateY(0.01)
            type.angle += 0.001 // 每次执行render角度新增加
            var x = type.data.revolutionR * Math.sin(type.angle) //地球x坐标计算
            var z = type.data.revolutionR * Math.cos(type.angle) //地球z坐标计算
            // 设置地球xz坐标，实现公转动画
            type.position.set(x, 0, z)
            // 计算相机和天体的距离
            const distance = camera.position.distanceTo(type.position)
            that.labelLst.forEach((type2) => {
              if (type2.name == type.name) {
                type2.position.set(x, 0, z)
                type2.visible = distance < 500 // 如果距离小于500，显示标签
              }
            })
          }
        })
        // 如果有最外侧的轨道纹理，可以让它轻微旋转

        renderer.render(scene, camera) //执行渲染操作
        labelRenderer.render(scene, camera) //执行渲染标签层
        requestAnimationFrame(render) //请求再次执行渲染函数render，渲染下一帧
      }

      // 创建Raycaster对象用于检测鼠标点击事件
      const raycaster = new THREE.Raycaster()
      const mouse = new THREE.Vector2()

      window.addEventListener('click', (event) => {
        mouse.x = (event.clientX / window.innerWidth) * 2 - 1
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1

        // 通过鼠标点的位置和当前相机更新Raycaster
        raycaster.setFromCamera(mouse, camera)

        // 计算物体和Raycaster的焦点
        const intersects = raycaster.intersectObjects(scene.children)

        // 如果有物体被点击
        if (intersects.length > 0) {
          const selectedObject = intersects[0].object
          if (selectedObject) alert(`点击了天体: ${selectedObject.name}`)

          // 这里可以弹出更多详细信息或使用UI框展示更多内容
        }
      })

      render()
      var controls = new OrbitControls(camera, renderer.domElement)
    },
    onWindowResize() {
      // Update camera
      const width = this.$refs.home.clientWidth
      const height = this.$refs.home.clientHeight
      camera.aspect = width / height
      camera.updateProjectionMatrix()
      console.log(
        camera.position.x + ',' + camera.position.y + ',' + camera.position.z
      )
      // Update renderer
      renderer.setSize(width, height)
      labelRenderer.setSize(width, height)
    },
    // 创建固定的参考轨道线
    // 修改 createFixedOrbits 生成固定轨道线，并为最外侧的轨道添加酷炫效果
    createGlowOrbitMaterial() {
      const textureLoader = new THREE.TextureLoader()
      const texture = textureLoader.load('/public/img/haiwangxing.jpg') // 加载轨道纹理

      return new THREE.MeshBasicMaterial({
        map: texture,
        transparent: true, // 使纹理的透明部分生效
        opacity: 0.8, // 设置不透明度
        side: THREE.DoubleSide, // 确保双面可见
      })
    },
    createFixedOrbits(scene) {
      const numOrbits = 5 // 轨道数量
      const minRadius = 100 // 最小轨道半径
      const gap = 150 // 每条轨道的间距

      for (let i = 0; i < numOrbits; i++) {
        const radius = minRadius + i * gap
        const arc = new THREE.ArcCurve(0, 0, radius, 0, 2 * Math.PI, true)
        const points = arc.getPoints(100)
        const lineGeometry = new THREE.BufferGeometry().setFromPoints(points)

        // 判断是否是最外侧轨道
        let material
        if (i === numOrbits - 1) {
          material = this.createGlowOrbitMaterial() // 为最外侧的轨道应用酷炫效果
        } else {
          material = new THREE.LineBasicMaterial({
            color: 0x0f4984,
            transparent: true,
            opacity: 0.5,
          })
        }

        const line = new THREE.LineLoop(lineGeometry, material)
        line.rotateX(Math.PI / 2)
        scene.add(line) // 添加轨道线到场景
      }
    },

 // 随机增加所有行星的分数
 increaseScore() {
    let maxScore = 0;

    // 随机增加每个行星的分数
    this.list.forEach((team) => {
      if (team.name !== '太阳') {  // 跳过太阳
        const randomIncrease =  10; // 随机增加1-10分
        // const randomIncrease = Math.floor(Math.random() * 10) + 1; // 随机增加1-10分
        team.score += randomIncrease;

        // 检查是否是当前最高分
        if (team.score > maxScore) {
          maxScore = team.score;
        }

        // 更新行星与太阳的距离
        const scoreRatio = team.score / this.totalScore;
        team.revolutionR = this.calculateRevolutionR(scoreRatio);
      }
    });

    // 检查最高分是否超过总分的 85%
    while (maxScore > this.totalScore * 0.85) {
      this.totalScore *= 1.2;  // 将总分增加 20%
      this.totalScore= this.totalScore.toFixed(0)
      setTimeout(() => {
        this.retreatPlanets();   // 所有行星后退
      }, 111);
      maxScore = Math.max(...this.list.map(team => team.score)).toFixed(0);  // 重新计算最高分
      this.HighScore = maxScore
      this.HighScoreAVE = this.HighScore/this.totalScore
    }
  },

  // 让所有行星统一后退一定距离，太阳不受影响
  retreatPlanets() {
    this.list.forEach((team) => {
      if (team.name !== '太阳') {  // 跳过太阳
        team.revolutionR += 20 * this.K;  // 所有行星统一后退 20 * K 的距离
      }
    });
  },

  // 计算 revolutionR，根据分数比例来计算行星距离
  calculateRevolutionR(scoreRatio) {
    const maxDistance = 120 * this.K; // 最大距离
    const minDistance = 30 * this.K;  // 最小距离
    return Math.max((1 - scoreRatio) * maxDistance, minDistance);
  },
  },
}
</script>

<style lang="scss">
.home {
  width: 100%;
  height: 100%;
  background: #053d79;
  position: fixed;
}

.tags {
  background: rgba(0, 0, 0, 0.5);
  padding: 10px 20px;
  color: #fff;
  font-size: 14px;
  border-radius: 5px;
  margin-top: -50px;
}
</style>
